# -*- coding: utf-8 -*-
"""
author: WenzhouZhang
date: 2020/8/23
"""
import threading
from functools import wraps

TIME_OUT = 10


class AsyncTaskManager(object):
    _asy_events = dict()

    def __init__(self, loop, *args):
        super(AsyncTaskManager, self).__init__()
        self._loop_fun = loop
        self._loop_proc = None
        self._running = True

    def __call__(self, *args, **kwargs):
        self._loop_proc = threading.Thread(target=self._exec_loop, args=args, kwargs=kwargs)
        self._loop_proc.setDaemon(True)
        self._loop_proc.start()
        return self

    def _exec_loop(self, *args, **kwargs):
        while self._running:
            net_resp = self._loop_fun(*args, **kwargs)
            for resp in net_resp:
                asy_event = self._asy_events.pop(resp.rid)
                asy_event.set()

    def stop(self):
        self._running = False

    @staticmethod
    def respond(func):
        @wraps(func)
        def make_resp(handle, tid):
            """ 需要注意的是，和装饰的函数参数含义需一致 """
            event = threading.Event()
            AsyncTaskManager._asy_events[tid] = event
            event.wait(timeout=TIME_OUT)
            return func(handle, tid)
        return make_resp

    @staticmethod
    def callback(func):
        @wraps(func)
        def make_thread(event, *args, **kwargs):
            event.wait(timeout=TIME_OUT)
            func(*args, **kwargs)

        def make_async(handle, tid):
            """ 注意点同上 """
            event = threading.Event()
            AsyncTaskManager._asy_events[tid] = event
            _task = threading.Thread(target=lambda: make_thread(event, handle, tid))

        return make_async


class AsyncCallback(object):

    def __init__(self, fun):
        super(AsyncCallback, self).__init__()
        self._ready = False
        self._fun = fun

    def __call__(self, *args, **kwargs):
        if self._fun:
            _task = threading.Thread(target=self._fun, args=args, kwargs=kwargs)
            _task.start()

    @property
    def ready(self):
        return self._ready

    @ready.setter
    def ready(self, is_ready):
        self._ready = is_ready


class SyncReturn(threading.Thread):

    def __init__(self):
        super(SyncReturn, self).__init__()
